﻿using CLVisionTrace;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WENYU_EIO16P;
using WENYU_PIO32P;
using static CLVisionLightControlTS.AbstractIODevice;
using static CLVisionLightControlTS.AbstractLightDevice;
using static LightControllerDll.CstClassLibControllerDll;
using static LightControllerDll.RsClassLibControllerDll;

namespace CLVisionLightControlTS
{

    public class IOTriggerControl
    {
        //实例化LogTrace对象（设成静态）
        private static LogTrace trace = new LogTrace();
        //准备日志保存路径
        private static MethodBase currentMethod = MethodBase.GetCurrentMethod();
        private static string namespaceName = currentMethod.DeclaringType.Namespace;
        private static string basePath = "D://OpconData//Trace";
        //记录日志全局开关
        private static bool g_LogEnable = true;
        public static bool G_LogEnable { get => g_LogEnable; set => g_LogEnable = value; }

        private static WENYU_PIO32P.EventInterrupt32 eventInterrupt;//中断事件定义
        private static int nCurCardID = 0;
        private static UInt16 RiseEnable = 0xffff;//DI端口上升沿中断使能公共变量
        private static UInt16 FallEnable = 0xffff;//DI端口下降沿中断使能公共变量

        //private static IOCard16 ioCard16 = new IOCard16();
        //private static IOCard32 ioCard32 = new IOCard32();

        private static AbstractIODevice IOCard = null;

        public static int Rs232_or_Ethernet = Rs232Mode; //EthernetMode
        public static int connect_state = 0;

        public static bool Init(LightBrand lightBrand, string IP, int iPort, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "Init successfully!";
            Occurred = false;
            try
            {
                if (lightBrand == LightBrand.CST)
                {
                    int ControllerHandle = 0;
                    int Ret = ConnectIP(IP, 1, ref ControllerHandle);
                    if (Ret == SUCCESS)
                    {
                        Rs232_or_Ethernet = EthernetMode;
                        connect_state = 1;
                    }
                    else
                    {
                        ErrorCode = -1;
                        ErrorText = $"{lightBrand.ToString()}:IP连接控制器失败，请检查光源控制软件是否已经连接该IP，或者检查网线！";
                        Occurred = true;
                        return false;
                    }
                    // 第二个参数 1:在线，2：脱机
                    Ret = SetDebugMode(Rs232_or_Ethernet, 2, ControllerHandle);
                    if (Ret != SUCCESS)
                    {
                        ErrorCode = -1;
                        ErrorText = $"{lightBrand.ToString()}:设置控制器脱机模式失败!";
                        Occurred = true;
                        return false;
                    }
                    // Mode-1：外触发，2：内触发，3：常亮
                    Ret = SetTriggerMode(Rs232_or_Ethernet, 1, ControllerHandle);
                    if (Ret != SUCCESS)
                    {
                        ErrorText = $"{lightBrand.ToString()}:设置外触发模式失败";
                        ErrorCode = 101;
                        Occurred = true;
                        return false;
                    }
                    // 第二个参数 1:IO触发模式，2：PLC触发模式
                    Ret = SetExternalTriggerMode(Rs232_or_Ethernet, 1, ControllerHandle);
                    if (Ret != SUCCESS)
                    {
                        ErrorCode = -1;
                        ErrorText = $"{lightBrand.ToString()}:设置IO触发模式失败！";
                        Occurred = true;
                        return false;
                    }
                    // 第二个参数 1:在线，2：脱机
                    Ret = SetDebugMode(Rs232_or_Ethernet, 1, ControllerHandle);
                    if (Ret != SUCCESS)
                    {
                        ErrorCode = -1;
                        ErrorText = $"{lightBrand.ToString()}:设置控制器在线模式失败!";
                        Occurred = true;
                        return false;
                    }

                    Ret = DestroyIpConnection(ControllerHandle); //断开IP连接
                    if (Ret == SUCCESS)
                    {
                        connect_state = 0;
                    }
                    else
                    {
                        ErrorCode = -1;
                        ErrorText = "断开IP失败";
                        Occurred = true;
                        return false;
                    }

                }
                else if (lightBrand == LightBrand.RS)
                {
                    uint DataSocket = RseeController_ConnectNet(IP, iPort);
                    if (DataSocket == 0)
                    {
                        ErrorCode = -200;
                        ErrorText = $"{lightBrand.ToString()}:IP连接控制器失败，请检查光源控制软件是否已经连接该IP，或者检查网线！";
                        Occurred = true;
                        return false;
                    }
                    // false:脱机模式  true:在线模式
                    int state = RseeController_P_S2_24V_10TCL_TriEn(DataSocket, false);
                    if (state != 0)
                    {
                        ErrorText = $"{lightBrand.ToString()}:设置脱机模式失败！";
                        Occurred = true;
                        return false;
                    }
                    // 工作模式，0：常亮模式  1：IO触发模式  2：PLC触发模式  3：内触发模式
                    state = RseeController_P_S2_24V_10TCL_TriMode(DataSocket, 1);
                    if (state != 0)
                    {
                        ErrorText = $"{lightBrand.ToString()}:设置IO触发模式失败！";
                        Occurred = true;
                        return false;
                    }
                    // false:脱机模式  true:在线模式
                    state = RseeController_P_S2_24V_10TCL_TriEn(DataSocket, true);
                    if (state != 0)
                    {
                        ErrorText = $"{lightBrand.ToString()}:设置在线模式失败！";
                        Occurred = true;
                        return false;
                    }
                    if (!RseeController_CloseNet(DataSocket))
                    {
                        ErrorCode = -201;
                        ErrorText = "网口断开失败";
                        Occurred = true;
                        return false; ;
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = "Init Fail！" + ex.Message + ex.StackTrace;
                Occurred = true;
                return false;
            }
        }
        /// <summary>
        /// 打开IO设备
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="cardType"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool OpenIODevice(int CardID, CardType cardType, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "OpenIODevice successfully!";
            Occurred = false;
            try
            {
                //设置日志路径和开关
                trace.SetLogPath(basePath + "//" + namespaceName);
                trace.G_LogEnable = g_LogEnable;

                nCurCardID = CardID;
                if (cardType == CardType.Card16)
                {
                    IOCard = new IOCard16();
                }
                else if (cardType == CardType.Card32)
                {
                    IOCard = new IOCard32();
                }
                IOCard.OpenIODevice(CardID, out ErrorCode, out ErrorText, out Occurred);
                if (ErrorCode != 0)
                {
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"{cardType.ToString()},device:{CardID} OpenIODevice Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 关闭IO设备
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool CloseIODevice(int CardID, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "CloseIODevice successfully!";
            Occurred = false;
            try
            {
                if (IOCard != null)
                {
                    IOCard.CloseIODevice(CardID, out ErrorCode, out ErrorText, out Occurred);
                    if (ErrorCode != 0)
                    {
                        trace.Error(ErrorText);
                        return false;
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"device:{CardID} CloseIODevice Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 按照光源配方号lightConfigNo触发DO
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="IOGroup"></param>
        /// <param name="lightConfigNo"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool TrigerLight(int CardID, int IOGroup, int lightConfigNo, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "TrigerLight successfully!";
            Occurred = false;
            try
            {
                IOCard.TriggerLight(CardID, IOGroup, lightConfigNo, out ErrorCode, out ErrorText, out Occurred);
                if (ErrorCode != 0)
                {
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"device:{CardID} TrigerLight Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 设置DO
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="OutPutData"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool SetOutPutData(int CardID, long OutPutData, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "SetOutPutData successfully!";
            Occurred = false;
            try
            {
                IOCard.SetOutPutData(CardID, OutPutData, out ErrorCode, out ErrorText, out Occurred);
                if (ErrorCode != 0)
                {
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"device:{CardID} SetOutPutData Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 获取DO
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="OutPutData"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool GetOutPutData(int CardID, out long OutPutData, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "GetOutPutData successfully!";
            Occurred = false;
            try
            {
                IOCard.GetOutPutData(CardID, out OutPutData, out ErrorCode, out ErrorText, out Occurred);
                if (ErrorCode != 0)
                {
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"device:{CardID} GetOutPutData Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                OutPutData = 0;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 获取DI
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="InPutData"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool GetInPutData(int CardID, out long InPutData, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "GetInPutData successfully!";
            Occurred = false;
            try
            {
                IOCard.GetInPutData(CardID, out InPutData, out ErrorCode, out ErrorText, out Occurred);
                if (ErrorCode != 0)
                {
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"device:{CardID} GetInPutData Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                InPutData = 0;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 设置DO Bit位
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="PortBit"></param>
        /// <param name="Value"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool WriteOutPutBit(int CardID, int PortBit, int Value, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "WriteOutPutBit successfully!";
            Occurred = false;
            try
            {
                IOCard.WriteOutPutBit(CardID, PortBit, Value, out ErrorCode, out ErrorText, out Occurred);
                if (ErrorCode != 0)
                {
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"device:{CardID} WriteOutPutBit {PortBit} Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 获取DO Bit位
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="PortBit"></param>
        /// <param name="Value"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool ReadOutPutBit(int CardID, int PortBit, out int Value, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "ReadOutPutBit successfully!";
            Occurred = false;
            try
            {
                IOCard.ReadOutPutBit(CardID, PortBit, out Value, out ErrorCode, out ErrorText, out Occurred);
                if (ErrorCode != 0)
                {
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"device:{CardID} ReadOutPutBit {PortBit} Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                Value = 0;
                trace.Error(ErrorText);
                return false;
            }
        }

        /// <summary>
        /// 获取DI Bit位
        /// </summary>
        /// <param name="CardID"></param>
        /// <param name="PortBit"></param>
        /// <param name="Value"></param>
        /// <param name="ErrorCode"></param>
        /// <param name="ErrorText"></param>
        /// <param name="Occurred"></param>
        /// <returns></returns>
        public static bool ReadInPutbit(int CardID, int PortBit, out int Value, out int ErrorCode, out string ErrorText, out bool Occurred)
        {
            ErrorCode = 0;
            ErrorText = "ReadInPutbit successfully!";
            Occurred = false;
            try
            {
                IOCard.ReadInPutbit(CardID, PortBit, out Value, out ErrorCode, out ErrorText, out Occurred);
                if (ErrorCode != 0)
                {
                    trace.Error(ErrorText);
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                ErrorCode = -1;
                ErrorText = $"device:{CardID} ReadInPutbit Failed!" + ex.Message + ex.StackTrace;
                Occurred = true;
                Value = 0;
                trace.Error(ErrorText);
                return false;
            }
        }
    }
}
